home *** CD-ROM | disk | FTP | other *** search
/ Cre@te Online 2000 December / Cre@teOnline CD05.iso / MacSoft / XML Instance.sea / XML Instance / Required / plugins / HTMLWindow.jar / horst / HTMLDocument.class (.txt) < prev    next >
Encoding:
Java Class File  |  2000-03-18  |  22.1 KB  |  1,093 lines

  1. package horst;
  2.  
  3. import horst.parser.HTMLDefs;
  4. import horst.parser.HTMLTags;
  5. import horst.parser.ParserCallback;
  6. import horst.parser.Tag;
  7. import java.awt.Color;
  8. import java.awt.Component;
  9. import java.awt.Font;
  10. import java.awt.Toolkit;
  11. import java.io.File;
  12. import java.io.FileOutputStream;
  13. import java.io.IOException;
  14. import java.io.PrintWriter;
  15. import java.net.URL;
  16. import java.util.Enumeration;
  17. import java.util.Hashtable;
  18. import java.util.Stack;
  19. import java.util.StringTokenizer;
  20. import java.util.Vector;
  21. import javax.swing.ComboBoxModel;
  22. import javax.swing.DefaultComboBoxModel;
  23. import javax.swing.DefaultListModel;
  24. import javax.swing.JComboBox;
  25. import javax.swing.JComponent;
  26. import javax.swing.JList;
  27. import javax.swing.JScrollPane;
  28. import javax.swing.JTextArea;
  29. import javax.swing.text.AttributeSet;
  30. import javax.swing.text.BadLocationException;
  31. import javax.swing.text.Document;
  32.  
  33. public class HTMLDocument implements ParserCallback {
  34.    protected String m_title = "";
  35.    protected Color m_linkColor;
  36.    protected Color m_textColor;
  37.    protected Color m_alinkColor;
  38.    protected URL m_url;
  39.    protected URL m_baseURL;
  40.    protected TagStack m_tagStack;
  41.    protected Stack m_characterStack;
  42.    protected Element m_rootElement;
  43.    protected Element m_baseElement;
  44.    protected HTMLDocument m_thisDoc;
  45.    protected String[] m_fontList;
  46.    protected Object m_formModel;
  47.    protected ComboBoxItem m_comboItem;
  48.    protected boolean m_bInOption;
  49.    protected boolean m_bInAnchor;
  50.    protected boolean m_bInTextArea;
  51.    protected boolean m_bInIFrame;
  52.    protected boolean m_bInTitle;
  53.    protected boolean m_bInPreformat;
  54.    protected Vector m_relatedElements;
  55.    protected Vector m_formProcessors;
  56.    protected HTMLPane m_renderer;
  57.    protected FormProcessor m_form;
  58.    protected StringBuffer m_textbuffer;
  59.    protected Vector m_mapElements;
  60.    protected File m_sourceFile;
  61.    protected URL m_refreshURL;
  62.    protected Vector m_anchors;
  63.    protected boolean m_bPrintTree;
  64.    protected int m_selectedP0;
  65.    protected int m_selectedP1;
  66.    private static PrintWriter pwOut;
  67.    private static int indent;
  68.  
  69.    public HTMLDocument(HTMLPane renderer) {
  70.       this.m_linkColor = Color.blue;
  71.       this.m_textColor = Color.black;
  72.       this.m_alinkColor = Color.red;
  73.       this.m_tagStack = new TagStack();
  74.       this.m_characterStack = new Stack();
  75.       this.m_bInOption = false;
  76.       this.m_bInAnchor = false;
  77.       this.m_bInTextArea = false;
  78.       this.m_bInIFrame = false;
  79.       this.m_bInTitle = false;
  80.       this.m_bInPreformat = false;
  81.       this.m_relatedElements = new Vector();
  82.       this.m_formProcessors = new Vector();
  83.       this.m_mapElements = new Vector();
  84.       this.m_anchors = new Vector();
  85.       this.m_bPrintTree = false;
  86.       this.m_selectedP0 = -1;
  87.       this.m_selectedP1 = -1;
  88.       this.m_renderer = renderer;
  89.       this.m_fontList = Toolkit.getDefaultToolkit().getFontList();
  90.       this.m_bInOption = false;
  91.       this.m_thisDoc = this;
  92.       this.m_baseElement = new Element(53);
  93.       this.m_textbuffer = new StringBuffer();
  94.    }
  95.  
  96.    final void checkOptionContext() {
  97.       if (this.m_bInOption && this.m_formModel instanceof DefaultComboBoxModel && this.m_comboItem != null) {
  98.          ((DefaultComboBoxModel)this.m_formModel).addElement(this.m_comboItem);
  99.       }
  100.  
  101.    }
  102.  
  103.    public static void closeLog() {
  104.       if (pwOut != null) {
  105.          pwOut.close();
  106.          pwOut = null;
  107.       }
  108.  
  109.    }
  110.  
  111.    protected TextAttributes createDefaultTextAttributes() {
  112.       TextAttributes atts = new TextAttributes(this.m_renderer.m_props.m_defaultFont);
  113.       atts.color = this.m_textColor;
  114.       return atts;
  115.    }
  116.  
  117.    protected void doStartElementTrap(Element elem) {
  118.       int type = elem.getType();
  119.       switch (type) {
  120.          case 10:
  121.          case 50:
  122.             this.m_anchors.addElement(elem);
  123.             break;
  124.          case 39:
  125.             String httpequiv = (String)elem.getAttribute("http-equiv");
  126.             if (httpequiv != null && httpequiv.equalsIgnoreCase("Refresh")) {
  127.                String content = (String)elem.getAttribute("content");
  128.                if (content != null) {
  129.                   content = content.toLowerCase();
  130.                   int idx = content.indexOf("url=");
  131.                   if (idx >= 0) {
  132.                      String urlStr = content.substring(idx + 4).trim();
  133.                      this.m_refreshURL = Utilities.getURL(urlStr);
  134.                   }
  135.                }
  136.             }
  137.             break;
  138.          case 47:
  139.             this.m_mapElements.addElement(elem);
  140.       }
  141.  
  142.    }
  143.  
  144.    public Element findElement(int type, String attribute, String value) {
  145.       return this.m_rootElement != null ? this.getElement(this.m_rootElement, type, attribute, value) : null;
  146.    }
  147.  
  148.    public void finishedParsing() {
  149.       if (this.m_rootElement != null) {
  150.          int nChildCount = this.m_rootElement.getElementCount();
  151.          if (nChildCount == 1) {
  152.             this.m_rootElement = this.m_rootElement.getElementAt(0);
  153.          } else {
  154.             this.m_rootElement.m_type = 0;
  155.          }
  156.  
  157.          this.m_rootElement.setDocument(this);
  158.          if (this.m_rootElement.getType() != 0) {
  159.             Element save = this.m_rootElement;
  160.             this.m_rootElement = new Element(0);
  161.             this.m_rootElement.addChild(save);
  162.          }
  163.  
  164.          if (this.m_bPrintTree) {
  165.             this.printTree(this.m_rootElement, 0);
  166.          }
  167.       }
  168.  
  169.       closeLog();
  170.    }
  171.  
  172.    public Element getAnchor(String name) {
  173.       Enumeration enum = this.m_anchors.elements();
  174.  
  175.       while(enum.hasMoreElements()) {
  176.          Element elem = (Element)enum.nextElement();
  177.          String val = (String)elem.getAttribute("name");
  178.          if (val != null && val.equalsIgnoreCase(name)) {
  179.             return elem;
  180.          }
  181.       }
  182.  
  183.       return null;
  184.    }
  185.  
  186.    public Element[] getAnchors() {
  187.       Element[] anchors = new Element[this.m_anchors.size()];
  188.       this.m_anchors.copyInto(anchors);
  189.       return anchors;
  190.    }
  191.  
  192.    public Enumeration getAnchorsEnumeration() {
  193.       return this.m_anchors.elements();
  194.    }
  195.  
  196.    public Element getBaseElement() {
  197.       return this.m_baseElement;
  198.    }
  199.  
  200.    public URL getBaseURL() {
  201.       return this.m_baseURL;
  202.    }
  203.  
  204.    protected String getDefaultFontFace() {
  205.       return this.m_renderer.m_props.m_defaultFont.getFamily();
  206.    }
  207.  
  208.    protected int getDefaultFontSize() {
  209.       return this.m_renderer.m_props.m_defaultFont.getSize();
  210.    }
  211.  
  212.    protected Element getElement(Element e, int type, String attribute, String value) {
  213.       if (e.getType() == type && e.isAttributeDefined(attribute) && ((String)e.getAttribute(attribute)).equals(value)) {
  214.          return e;
  215.       } else {
  216.          int nChildren = e.getElementCount();
  217.  
  218.          for(int i = 0; i < nChildren; ++i) {
  219.             Element result = this.getElement(e.getElementAt(i), type, attribute, value);
  220.             if (result != null) {
  221.                return result;
  222.             }
  223.          }
  224.  
  225.          return null;
  226.       }
  227.    }
  228.  
  229.    protected String getElementName(Element e) {
  230.       return e.getName();
  231.    }
  232.  
  233.    public Vector getFormProcessors() {
  234.       return this.m_formProcessors;
  235.    }
  236.  
  237.    public Color getLinkColor() {
  238.       return this.m_linkColor;
  239.    }
  240.  
  241.    public Element getMapElement(Element areaElem) {
  242.       Enumeration enum = this.m_mapElements.elements();
  243.  
  244.       while(enum.hasMoreElements()) {
  245.          Element elem = (Element)enum.nextElement();
  246.          Vector v = elem.getChildren();
  247.  
  248.          for(int i = 0; i < v.size(); ++i) {
  249.             if (v.elementAt(i) == areaElem) {
  250.                return elem;
  251.             }
  252.          }
  253.       }
  254.  
  255.       return null;
  256.    }
  257.  
  258.    public Enumeration getMapElements() {
  259.       return this.m_mapElements.elements();
  260.    }
  261.  
  262.    public Element getRootElement() {
  263.       return this.m_rootElement;
  264.    }
  265.  
  266.    protected TextAttributes getTextAttributes(Tag t) {
  267.       TextAttributes atts = null;
  268.       if (!this.m_characterStack.empty()) {
  269.          atts = new TextAttributes((TextAttributes)this.m_characterStack.peek());
  270.       } else {
  271.          atts = this.createDefaultTextAttributes();
  272.       }
  273.  
  274.       return atts;
  275.    }
  276.  
  277.    public StringBuffer getTextBuffer() {
  278.       return this.m_textbuffer;
  279.    }
  280.  
  281.    public Color getTextColor() {
  282.       return this.m_textColor;
  283.    }
  284.  
  285.    public String getTitle() {
  286.       return this.m_title;
  287.    }
  288.  
  289.    public URL getURL() {
  290.       return this.m_url;
  291.    }
  292.  
  293.    protected TextAttributes handleAnchor(Tag t, boolean bStart) {
  294.       this.m_bInAnchor = bStart;
  295.       TextAttributes atts = null;
  296.       if (bStart) {
  297.          atts = this.getTextAttributes(t);
  298.          String href = (String)t.getAttribute("href");
  299.          if (href != null) {
  300.             atts.color = this.m_linkColor;
  301.             atts.bUnderline = true;
  302.             URL u = Utilities.getURL(this.m_baseURL, href);
  303.             if (u != null) {
  304.                atts.href = u.toString();
  305.             } else {
  306.                atts.href = href;
  307.             }
  308.          }
  309.  
  310.          String target = (String)t.getAttribute("target");
  311.          if (target != null) {
  312.             atts.target = target;
  313.          }
  314.  
  315.          if (atts != null) {
  316.             this.m_characterStack.push(atts);
  317.          }
  318.  
  319.          this.handleBlockStart(t);
  320.       } else {
  321.          Element[] elems = new Element[this.m_relatedElements.size()];
  322.          this.m_relatedElements.copyInto(elems);
  323.          if (elems.length > 1) {
  324.             for(int i = 0; i < elems.length; ++i) {
  325.                Element currentElem = elems[i];
  326.  
  327.                for(int j = 0; j < elems.length; ++j) {
  328.                   if (currentElem != elems[j]) {
  329.                      elems[j].addRelatedElement(currentElem);
  330.                   }
  331.                }
  332.             }
  333.          }
  334.  
  335.          if (elems.length > 0) {
  336.             int sz = this.m_anchors.size();
  337.             if (sz > 0) {
  338.                Element currAnchor = (Element)this.m_anchors.elementAt(sz - 1);
  339.  
  340.                for(int j = 0; j < elems.length; ++j) {
  341.                   currAnchor.addRelatedElement(elems[j]);
  342.                   elems[j].m_anchor = currAnchor;
  343.                }
  344.             }
  345.          }
  346.  
  347.          this.m_relatedElements.removeAllElements();
  348.          if (!this.m_characterStack.empty()) {
  349.             this.m_characterStack.pop();
  350.          }
  351.  
  352.          this.handleBlockEnd(t);
  353.       }
  354.  
  355.       return atts;
  356.    }
  357.  
  358.    protected void handleBlockEnd(Tag t) {
  359.       switch (t.getID()) {
  360.          case 2:
  361.          case 4:
  362.          case 5:
  363.          case 14:
  364.          case 15:
  365.          case 16:
  366.          case 17:
  367.          case 18:
  368.          case 19:
  369.          case 64:
  370.             if (!this.m_characterStack.empty()) {
  371.                this.m_characterStack.pop();
  372.             }
  373.             break;
  374.          case 13:
  375.             this.m_bInTitle = false;
  376.             return;
  377.          case 31:
  378.             this.m_formModel = null;
  379.             break;
  380.          case 32:
  381.             this.m_bInTextArea = false;
  382.             this.m_formModel = null;
  383.             break;
  384.          case 54:
  385.             this.checkOptionContext();
  386.             this.m_bInOption = false;
  387.             this.m_comboItem = null;
  388.             break;
  389.          case 67:
  390.             this.m_bInIFrame = false;
  391.       }
  392.  
  393.       if (!this.m_tagStack.empty()) {
  394.          Element stackElem = (Element)this.m_tagStack.peek();
  395.          if (stackElem.getType() == t.getID()) {
  396.             this.m_tagStack.pop();
  397.          } else {
  398.             switch (t.getID()) {
  399.                case 1:
  400.                   int[] tagIDs = new int[2];
  401.                   tagIDs[0] = 1;
  402.                   tagIDs[1] = 0;
  403.                   Element e = this.m_tagStack.getFirstElementType(tagIDs);
  404.                   if (e != null && e.getType() == 1) {
  405.                      this.m_tagStack.popElement(e);
  406.                   }
  407.                   break;
  408.                case 3:
  409.                case 5:
  410.                case 8:
  411.                case 12:
  412.                   if (stackElem.getType() == 6 && this.m_tagStack.size() > 1) {
  413.                      Element paraElem = (Element)this.m_tagStack.pop();
  414.                      stackElem = (Element)this.m_tagStack.peek();
  415.                      if (stackElem.getType() == t.getID()) {
  416.                         this.m_tagStack.pop();
  417.                      } else {
  418.                         this.m_tagStack.push(paraElem);
  419.                      }
  420.                   }
  421.                case 6:
  422.                   break;
  423.                default:
  424.                   Element e = this.m_tagStack.getElementType(t.getID());
  425.                   if (e != null) {
  426.                      this.m_tagStack.popElement(e);
  427.                   }
  428.             }
  429.          }
  430.       }
  431.  
  432.    }
  433.  
  434.    protected void handleBlockStart(Tag t) {
  435.       if (this.m_tagStack.empty() && t.getID() != 1 && t.getID() != 0) {
  436.          this.m_rootElement = new Element(0);
  437.          this.setBufferPointers(this.m_rootElement);
  438.          this.m_tagStack.push(this.m_rootElement);
  439.       }
  440.  
  441.       switch (t.getID()) {
  442.          case 1:
  443.             this.m_linkColor = Utilities.setColorProperty(Color.blue, "link", t.getAttributes());
  444.             this.m_textColor = Utilities.setColorProperty(Color.black, "text", t.getAttributes());
  445.             this.m_alinkColor = Utilities.setColorProperty(Color.red, "alink", t.getAttributes());
  446.             break;
  447.          case 2:
  448.          case 5:
  449.             this.m_characterStack.push(this.createDefaultTextAttributes());
  450.             break;
  451.          case 4:
  452.             TextAttributes textAtts = this.createDefaultTextAttributes();
  453.             textAtts.font = new Font(this.getDefaultFontFace(), 1, this.getDefaultFontSize());
  454.             this.m_characterStack.push(textAtts);
  455.             break;
  456.          case 13:
  457.             this.m_bInTitle = true;
  458.             return;
  459.          case 14:
  460.          case 15:
  461.          case 16:
  462.          case 17:
  463.          case 18:
  464.          case 19:
  465.             this.handleHeadingStart(t);
  466.             break;
  467.          case 27:
  468.             if (!this.m_tagStack.empty()) {
  469.                Element stackElem = (Element)this.m_tagStack.peek();
  470.                if (stackElem.getType() == 27) {
  471.                   this.m_tagStack.pop();
  472.                }
  473.             }
  474.             break;
  475.          case 30:
  476.             Component c = Utilities.createFormComponent(this.m_thisDoc, t);
  477.             if (c != null) {
  478.                t.setAttribute("component", c);
  479.             }
  480.  
  481.             if (this.m_form != null) {
  482.                Element formElem = new Element(t.getID());
  483.                this.setBufferPointers(formElem);
  484.                formElem.setAttributes(t.getAttributesCopy());
  485.                this.m_form.addComponent(formElem);
  486.             }
  487.             break;
  488.          case 31:
  489.             this.handleSelect(t);
  490.             break;
  491.          case 32:
  492.             Component c = Utilities.createFormComponent(this.m_thisDoc, t);
  493.             if (c != null) {
  494.                this.m_formModel = ((JTextArea)c).getDocument();
  495.                JScrollPane pane = new JScrollPane(c, 22, 32);
  496.                t.setAttribute("component", pane);
  497.             }
  498.  
  499.             this.m_bInTextArea = true;
  500.             break;
  501.          case 54:
  502.             this.checkOptionContext();
  503.             this.m_bInOption = true;
  504.             this.m_comboItem = new ComboBoxItem(t);
  505.             break;
  506.          case 64:
  507.             TextAttributes currentAtts = this.getTextAttributes(t);
  508.             currentAtts.font = new Font("Serif", 2, 12);
  509.             this.m_characterStack.push(currentAtts);
  510.             break;
  511.          case 67:
  512.             if (!this.m_renderer.m_preferences.m_bIFramesEnabled) {
  513.                return;
  514.             }
  515.  
  516.             this.m_bInIFrame = true;
  517.       }
  518.  
  519.       Element elem = new Element(t.getID());
  520.       this.setBufferPointers(elem);
  521.       elem.setDocument(this);
  522.       elem.setAttributes(t.getAttributesCopy());
  523.       this.setTextAttributes(elem);
  524.       if (this.m_bInAnchor) {
  525.          int sz = this.m_anchors.size();
  526.          if (sz > 0) {
  527.             Element anchor = (Element)this.m_anchors.elementAt(sz - 1);
  528.             anchor.addRelatedElement(elem);
  529.          }
  530.       }
  531.  
  532.       int contextCheck = ContextChecker.checkContext(elem, this.m_tagStack, this.m_characterStack);
  533.       if (contextCheck == 0) {
  534.          this.doStartElementTrap(elem);
  535.          if (!this.m_tagStack.empty()) {
  536.             ((Element)this.m_tagStack.peek()).addChild(elem);
  537.          }
  538.  
  539.          if (t.isBlockTag()) {
  540.             if (this.m_tagStack.empty()) {
  541.                this.m_rootElement = elem;
  542.             }
  543.  
  544.             this.m_tagStack.push(elem);
  545.          }
  546.       }
  547.  
  548.    }
  549.  
  550.    protected void handleCharacterEnd(Tag t) {
  551.       switch (t.getID()) {
  552.          case 52:
  553.             this.handleFont(t, false);
  554.             break;
  555.          default:
  556.             if (!this.m_characterStack.empty()) {
  557.                this.m_characterStack.pop();
  558.             }
  559.       }
  560.  
  561.    }
  562.  
  563.    protected void handleCharacterStart(Tag t) {
  564.       TextAttributes currentAtts = this.getTextAttributes(t);
  565.       int style = currentAtts.font.getStyle();
  566.       switch (t.getID()) {
  567.          case 28:
  568.          case 56:
  569.          case 57:
  570.             currentAtts.font = new Font("Monospaced", 0, 12);
  571.             break;
  572.          case 38:
  573.          case 60:
  574.             style |= 2;
  575.             currentAtts.font = new Font(currentAtts.font.getName(), style, currentAtts.font.getSize());
  576.             break;
  577.          case 40:
  578.          case 42:
  579.             style |= 1;
  580.             currentAtts.font = new Font(currentAtts.font.getName(), style, currentAtts.font.getSize());
  581.             break;
  582.          case 41:
  583.             currentAtts.font = new Font(currentAtts.font.getFamily(), currentAtts.font.getStyle(), currentAtts.font.getSize() - 1);
  584.             break;
  585.          case 48:
  586.             currentAtts.font = new Font(currentAtts.font.getFamily(), currentAtts.font.getStyle(), currentAtts.font.getSize() + 1);
  587.             break;
  588.          case 52:
  589.          case 72:
  590.             currentAtts = this.handleFont(t, true);
  591.             break;
  592.          case 55:
  593.             currentAtts.bUnderline = true;
  594.             break;
  595.          case 58:
  596.             currentAtts.setAttribute("subscript", "true");
  597.             break;
  598.          case 59:
  599.             currentAtts.setAttribute("superscript", "true");
  600.             break;
  601.          case 68:
  602.             currentAtts.font = new Font("sansserif", 0, 12);
  603.             break;
  604.          default:
  605.             return;
  606.       }
  607.  
  608.       if (currentAtts != null) {
  609.          this.m_characterStack.push(currentAtts);
  610.       }
  611.  
  612.    }
  613.  
  614.    public void handleContent(StringBuffer buf) {
  615.       if (this.m_bInTitle) {
  616.          this.m_title = this.m_title + buf.toString();
  617.       } else if (!this.m_bInIFrame) {
  618.          if (this.m_bInOption && this.m_formModel != null) {
  619.             if (this.m_formModel instanceof DefaultComboBoxModel && this.m_comboItem != null) {
  620.                ComboBoxItem var10003 = this.m_comboItem;
  621.                var10003.m_text = var10003.m_text + buf.toString();
  622.             } else if (this.m_formModel instanceof DefaultListModel) {
  623.                String s = buf.toString();
  624.                if (!Utilities.isBlankSpaces(s)) {
  625.                   ((DefaultListModel)this.m_formModel).addElement(buf.toString());
  626.                }
  627.             }
  628.          } else if (this.m_bInTextArea && this.m_formModel != null) {
  629.             if (this.m_formModel instanceof Document) {
  630.                Document d = (Document)this.m_formModel;
  631.  
  632.                try {
  633.                   d.insertString(d.getLength(), buf.toString(), (AttributeSet)null);
  634.                } catch (BadLocationException var4) {
  635.                }
  636.             }
  637.          } else {
  638.             Element elem = new Element(9);
  639.             this.setBufferPointers(elem, buf);
  640.             elem.setDocument(this);
  641.             this.setTextAttributes(elem);
  642.             if (this.m_bInAnchor) {
  643.                this.m_relatedElements.addElement(elem);
  644.             }
  645.  
  646.             if (this.m_tagStack.empty()) {
  647.                this.m_rootElement = new Element(0);
  648.                this.setBufferPointers(this.m_rootElement);
  649.                this.m_tagStack.push(this.m_rootElement);
  650.             }
  651.  
  652.             Element e = (Element)this.m_tagStack.peek();
  653.             e.addChild(elem);
  654.          }
  655.  
  656.       }
  657.    }
  658.  
  659.    protected TextAttributes handleFont(Tag t, boolean bStart) {
  660.       TextAttributes currentAtts = this.getTextAttributes(t);
  661.       String color = (String)t.getAttribute("color");
  662.       if (color != null) {
  663.          Color c = Utilities.stringToColor(color);
  664.          if (c != null) {
  665.             currentAtts.color = c;
  666.          }
  667.       }
  668.  
  669.       String face = currentAtts.font.getFamily();
  670.       String value = (String)t.getAttribute("face");
  671.       if (value != null) {
  672.          value = value.toLowerCase();
  673.          String fontName = this.getDefaultFontFace();
  674.          StringTokenizer st = new StringTokenizer(value, ",");
  675.  
  676.          while(st.hasMoreTokens()) {
  677.             String tok = st.nextToken().trim();
  678.             if (tok.equals("arial")) {
  679.                fontName = "sansserif";
  680.                break;
  681.             }
  682.  
  683.             if (this.haveFont(tok)) {
  684.                fontName = tok;
  685.                break;
  686.             }
  687.  
  688.             if (tok.equals("courier") || tok.equals("monospaced")) {
  689.                fontName = "courier";
  690.                break;
  691.             }
  692.  
  693.             if (tok.equals("helvetica")) {
  694.                fontName = "sansserif";
  695.                break;
  696.             }
  697.          }
  698.  
  699.          face = fontName;
  700.       }
  701.  
  702.       int size = currentAtts.font.getSize();
  703.       value = (String)t.getAttribute("size");
  704.       if (value != null) {
  705.          int fs = TextAttributes.getFontSize(this.getDefaultFontSize(), value);
  706.          if (fs != -1) {
  707.             size = fs;
  708.          }
  709.       }
  710.  
  711.       int style = currentAtts.font.getStyle();
  712.       value = (String)t.getAttribute("style");
  713.       int idx;
  714.       if (value != null) {
  715.          do {
  716.             idx = value.indexOf(59);
  717.             if (idx != -1 || idx == -1 && value.length() > 0) {
  718.                String s;
  719.                if (idx != -1) {
  720.                   s = value.substring(0, idx);
  721.                } else {
  722.                   s = value;
  723.                }
  724.  
  725.                int colonIndex = s.indexOf(58);
  726.                if (colonIndex != -1) {
  727.                   String keyValue = null;
  728.                   String key = s.substring(0, colonIndex).trim();
  729.                   if (colonIndex != s.length() - 1) {
  730.                      keyValue = s.substring(colonIndex + 1).trim();
  731.                   }
  732.  
  733.                   if (keyValue != null) {
  734.                      if (key.equalsIgnoreCase("font-size")) {
  735.                         int ptIdx = keyValue.indexOf("pt");
  736.                         if (ptIdx != -1) {
  737.                            try {
  738.                               size = Integer.parseInt(keyValue.substring(0, ptIdx));
  739.                            } catch (NumberFormatException var15) {
  740.                            }
  741.                         }
  742.                      } else if (key.equalsIgnoreCase("color")) {
  743.                         Color c = Utilities.stringToColor(keyValue);
  744.                         if (c != null) {
  745.                            currentAtts.color = c;
  746.                         }
  747.                      }
  748.                   }
  749.                }
  750.  
  751.                if (idx != -1) {
  752.                   if (idx == value.length() - 1) {
  753.                      break;
  754.                   }
  755.  
  756.                   value = value.substring(idx + 1);
  757.                }
  758.             }
  759.          } while(idx != -1);
  760.       }
  761.  
  762.       currentAtts.font = new Font(face, style, size);
  763.       if (!bStart && !this.m_characterStack.empty()) {
  764.          this.m_characterStack.pop();
  765.       }
  766.  
  767.       return currentAtts;
  768.    }
  769.  
  770.    protected void handleHeadingStart(Tag t) {
  771.       TextAttributes currentAtts = this.getTextAttributes(t);
  772.       String face = currentAtts.font.getFamily();
  773.       int style = 1;
  774.       int defaultSize = this.getDefaultFontSize();
  775.       int size;
  776.       switch (t.getID()) {
  777.          case 14:
  778.             size = defaultSize + 6;
  779.             break;
  780.          case 15:
  781.             size = defaultSize + 4;
  782.             break;
  783.          case 16:
  784.             size = defaultSize + 2;
  785.             break;
  786.          case 17:
  787.             size = defaultSize;
  788.             break;
  789.          case 18:
  790.             size = defaultSize - 1;
  791.             break;
  792.          case 19:
  793.             size = defaultSize - 2;
  794.             break;
  795.          default:
  796.             size = defaultSize;
  797.       }
  798.  
  799.       currentAtts.font = new Font(face, style, size);
  800.       this.m_characterStack.push(currentAtts);
  801.    }
  802.  
  803.    public void handleNoBreakSpace() {
  804.       if (!this.m_bInIFrame) {
  805.          Element elem = new Element(101);
  806.          this.setBufferPointers(elem);
  807.          elem.setDocument(this);
  808.          this.setTextAttributes(elem);
  809.          if (this.m_bInAnchor) {
  810.             this.m_relatedElements.addElement(elem);
  811.          }
  812.  
  813.          if (!this.m_tagStack.empty()) {
  814.             Element e = (Element)this.m_tagStack.peek();
  815.             e.addChild(elem);
  816.          }
  817.  
  818.       }
  819.    }
  820.  
  821.    protected void handleSelect(Tag t) {
  822.       JComponent c = null;
  823.       Object var4;
  824.       if (t.isAttributeDefined("multiple")) {
  825.          this.m_formModel = new DefaultListModel();
  826.          JList list = new JList((DefaultListModel)this.m_formModel);
  827.          var4 = new JScrollPane(list);
  828.       } else {
  829.          this.m_formModel = new DefaultComboBoxModel();
  830.          var4 = new JComboBox((ComboBoxModel)this.m_formModel);
  831.       }
  832.  
  833.       t.setAttribute("component", var4);
  834.       if (this.m_form != null) {
  835.          Element e = new Element(t.getID());
  836.          this.setBufferPointers(e);
  837.          e.setAttributes(t.getAttributesCopy());
  838.          this.m_form.addComponent(e);
  839.       }
  840.  
  841.    }
  842.  
  843.    public void handleTag(Tag t, boolean bStartTag) {
  844.       if (!this.m_bInIFrame || t.getID() == 67 && !bStartTag) {
  845.          switch (t.getID()) {
  846.             case 10:
  847.                this.handleAnchor(t, bStartTag);
  848.                break;
  849.             case 28:
  850.                this.m_bInPreformat = bStartTag;
  851.             case 38:
  852.             case 40:
  853.             case 41:
  854.             case 42:
  855.             case 46:
  856.             case 48:
  857.             case 52:
  858.             case 55:
  859.             case 56:
  860.             case 57:
  861.             case 58:
  862.             case 59:
  863.             case 60:
  864.             case 65:
  865.             case 68:
  866.             case 72:
  867.             case 73:
  868.             case 74:
  869.                if (bStartTag) {
  870.                   this.handleCharacterStart(t);
  871.                } else {
  872.                   this.handleCharacterEnd(t);
  873.                }
  874.                break;
  875.             case 34:
  876.             case 63:
  877.             case 75:
  878.             case 76:
  879.             case 77:
  880.             case 78:
  881.                return;
  882.             case 53:
  883.                this.m_baseElement.setAttributes(t.getAttributesCopy());
  884.                URL u = Utilities.setURLProperty((URL)null, "href", t.getAttributes());
  885.                if (u != null) {
  886.                   this.m_baseURL = u;
  887.                }
  888.             default:
  889.                if (bStartTag) {
  890.                   this.handleBlockStart(t);
  891.                } else {
  892.                   this.handleBlockEnd(t);
  893.                }
  894.                break;
  895.             case 66:
  896.                if (bStartTag) {
  897.                   this.m_form = new FormProcessor(this.m_renderer, t.getAttributesCopy());
  898.                } else if (this.m_form != null) {
  899.                   this.m_formProcessors.addElement(this.m_form);
  900.                   this.m_form = null;
  901.                }
  902.  
  903.                return;
  904.          }
  905.  
  906.       }
  907.    }
  908.  
  909.    protected boolean haveFont(String face) {
  910.       if (this.m_fontList != null) {
  911.          for(int i = 0; i < this.m_fontList.length; ++i) {
  912.             if (this.m_fontList[i].equalsIgnoreCase(face)) {
  913.                return true;
  914.             }
  915.          }
  916.       }
  917.  
  918.       return false;
  919.    }
  920.  
  921.    public boolean isTextSelected() {
  922.       return this.m_selectedP0 != -1 && this.m_selectedP1 != -1;
  923.    }
  924.  
  925.    public void printDebugTree() {
  926.       this.printTree(this.m_rootElement, 0);
  927.       closeLog();
  928.    }
  929.  
  930.    void printTree(Element e, int index) {
  931.       String indent = "";
  932.  
  933.       for(int i = 0; i < index; ++i) {
  934.          indent = indent + ' ';
  935.       }
  936.  
  937.       String attStr = "";
  938.       Hashtable atts = e.getAttributes();
  939.       Enumeration enum = atts.keys();
  940.  
  941.       while(enum.hasMoreElements()) {
  942.          Object key = enum.nextElement();
  943.          Object value = atts.get(key);
  944.          if (value != null) {
  945.             attStr = attStr + " " + key + "=" + value;
  946.          }
  947.       }
  948.  
  949.       if (e.getType() == 9) {
  950.          String style = "";
  951.          Font f = e.getFont();
  952.          if (f != null) {
  953.             style = String.valueOf(f.getStyle());
  954.          }
  955.  
  956.          String str = new String(e.getCharData());
  957.          toLog(indent + this.getElementName(e) + " :x" + str + "x(" + attStr + ") style= " + style, 0);
  958.       } else {
  959.          toLog(indent + this.getElementName(e) + "  (" + attStr + ")", 0);
  960.       }
  961.  
  962.       index += 2;
  963.  
  964.       for(int i = 0; i < e.getElementCount(); ++i) {
  965.          this.printTree(e.getElementAt(i), index);
  966.       }
  967.  
  968.    }
  969.  
  970.    public void resetElements() {
  971.       if (this.m_rootElement != null) {
  972.          this.m_rootElement.reset();
  973.       }
  974.  
  975.    }
  976.  
  977.    protected void setBufferPointers(Element elem) {
  978.       int p0 = this.m_textbuffer.length();
  979.       elem.setTextPointers(p0, p0);
  980.    }
  981.  
  982.    protected void setBufferPointers(Element elem, StringBuffer buffer) {
  983.       int p0 = this.m_textbuffer.length();
  984.       char[] data = new char[buffer.length()];
  985.       buffer.getChars(0, buffer.length(), data, 0);
  986.       this.m_textbuffer.append(data);
  987.       int p1 = this.m_textbuffer.length() - 1;
  988.       elem.setTextPointers(p0, p1);
  989.    }
  990.  
  991.    protected void setTextAttributes(Element elem) {
  992.       TextAttributes atts = null;
  993.       if (!this.m_characterStack.empty()) {
  994.          atts = (TextAttributes)this.m_characterStack.peek();
  995.       } else {
  996.          atts = this.createDefaultTextAttributes();
  997.       }
  998.  
  999.       atts.multiplexAttributes(elem);
  1000.       elem.m_focusColor = this.m_alinkColor;
  1001.       elem.setFont(atts.font);
  1002.       elem.m_bInPreformat = this.m_bInPreformat;
  1003.    }
  1004.  
  1005.    public void startingParsing(URL u) {
  1006.       this.m_url = u;
  1007.       this.m_baseURL = u;
  1008.       this.m_textbuffer.setLength(0);
  1009.       this.m_rootElement = new Element(100);
  1010.       this.m_tagStack.removeAllElements();
  1011.       this.m_tagStack.push(this.m_rootElement);
  1012.       this.m_renderer.notifyStatusListeners(1, this.m_baseURL);
  1013.    }
  1014.  
  1015.    public static void toLog(String str, int nIndent) {
  1016.       if (pwOut == null) {
  1017.          try {
  1018.             String dir = System.getProperty("user.dir");
  1019.             FileOutputStream fOut = new FileOutputStream(dir + "\\parser.log");
  1020.             pwOut = new PrintWriter(fOut);
  1021.          } catch (IOException e) {
  1022.             ((Throwable)e).printStackTrace();
  1023.          }
  1024.       }
  1025.  
  1026.       if (nIndent > 0) {
  1027.          indent += nIndent;
  1028.       }
  1029.  
  1030.       String identStr = "";
  1031.  
  1032.       for(int i = 0; i < indent; ++i) {
  1033.          identStr = identStr + " ";
  1034.       }
  1035.  
  1036.       pwOut.println(identStr + str);
  1037.       if (nIndent < 0) {
  1038.          indent += nIndent;
  1039.       }
  1040.  
  1041.    }
  1042.  
  1043.    public void unSelectText() {
  1044.       this.m_selectedP0 = -1;
  1045.       this.m_selectedP1 = -1;
  1046.    }
  1047.  
  1048.    protected void writeElement(HTMLTags tags, PrintWriter out, Element e, int nIndent) {
  1049.       String s = "";
  1050.       boolean bBlock = false;
  1051.       boolean bBreaksFlow = false;
  1052.       String name = HTMLDefs.getName(e.getType());
  1053.       if (name != null) {
  1054.          Tag t = tags.getTag(name);
  1055.          if (t != null) {
  1056.             bBlock = t.isBlockTag();
  1057.             bBreaksFlow = t.breaksFlow();
  1058.          }
  1059.       }
  1060.  
  1061.       if (bBlock || bBreaksFlow) {
  1062.          for(int i = 0; i < nIndent; ++i) {
  1063.             s = s + " ";
  1064.          }
  1065.  
  1066.          out.println("");
  1067.       }
  1068.  
  1069.       out.print(s + e.toString());
  1070.       nIndent += 4;
  1071.  
  1072.       for(int i = 0; i < e.getElementCount(); ++i) {
  1073.          Element elem = e.getElementAt(i);
  1074.          if (elem != null) {
  1075.             this.writeElement(tags, out, elem, nIndent);
  1076.          }
  1077.       }
  1078.  
  1079.       if (bBlock) {
  1080.          out.println("");
  1081.          out.println(s + "</" + e.getName() + ">");
  1082.       }
  1083.  
  1084.    }
  1085.  
  1086.    public void writeToStream(PrintWriter out) {
  1087.       if (this.m_rootElement != null) {
  1088.          this.writeElement(new HTMLTags(), out, this.m_rootElement, 0);
  1089.       }
  1090.  
  1091.    }
  1092. }
  1093.